Skip to content

Conversation

@amol-
Copy link
Collaborator

@amol- amol- commented Jun 6, 2025

Intent

Allows to deploy content without activating it.

Type of Change

  • New Feature

Approach

New command line option that injects the parameter only when necessary, this way it will be backward compatible with previous API when the parameter is not provided.

Automated Tests

test_deploy_draft runs the command with all possible permutations of content and activate=True/False

Directions for Reviewers

Currently the deploy doesn't output the url where the draft can be seen, that's planned for a follow-up PR as the two can be done in isolation.

Checklist

  • I have updated CHANGELOG.md to cover notable changes.
  • I have updated all related GitHub issues to reflect their current state.

@github-actions
Copy link

github-actions bot commented Jun 6, 2025

PR Preview Action v1.6.1
Preview removed because the pull request was closed.
2025-06-11 16:10 UTC

@github-actions
Copy link

github-actions bot commented Jun 6, 2025

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
5110 3977 78% 0% 🟢

New Files

No new covered files...

Modified Files

File Coverage Status
rsconnect/api.py 77% 🟢
rsconnect/http_support.py 81% 🟢
rsconnect/main.py 69% 🟢
TOTAL 76% 🟢

updated for commit: 5be397a by action🐍

@amol- amol- marked this pull request as ready for review June 6, 2025 15:09
["voila", get_dir(join("pip1", "dummy.ipynb"))],
]
],
)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing, but in practice it produces product of args * flag thus testing every deploy command with both flag=True and flag=False

return (
response.json_data
if response.status and response.status == 200 and response.json_data is not None
if response.status and response.status >= 200 and response.status <= 299 and response.json_data is not None
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/content/X/deploy responds with a 201 and a JSON body

for key, value in headers.items():
logger.debug("--> %s: %s" % (key, value))
logger.debug("Body:")
logger.debug("--> %s" % (body if body is not None else "<no body>"))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this extra logging of the Request body when in debug (-vvv) for convenient to see what the client exchanged with the server.

args.extend(["--cacert", cacert])
if insecure:
args.extend(["--insecure"])
return args
Copy link
Collaborator Author

@amol- amol- Jun 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convenience so that I can do

args = apply_common_args(["deploy", command, target], server="http://fake_server", key="FAKE_API_KEY")

instead of

args = ["deploy", command, target]
apply_common_args(args, server="http://fake_server", key="FAKE_API_KEY")

semantically is not the best that it both modifies in place and also returns the value as it might be confusing that the two are the same, but given that it's just a test helper it shouldn't be a big deal.

@amol- amol- requested a review from marcosnav June 10, 2025 17:01
app_bundle = self.app_upload(app_id, tarball)

task = self.app_deploy(app_id, app_bundle["id"])
task = self.content_deploy(app_guid, app_bundle["id"], activate=activate)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the only use of app_deploy, it might be worth clearing it up

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

app_deploy is in api, there were other APIs that were not used. I think it makes sense to cover all apis in the API module, independently from the ones we use. But if we are strong about removing the ones we don't use I'm ok with removing them.

Copy link
Contributor

@marcosnav marcosnav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation wise, looks good to me, a couple non blocker items:

  • It'd be nice to clean up the app_deploy
  • I'm starting to question the use of the term "draft"

@edavidaja
Copy link
Collaborator

I thought we were calling this preview? or did we change the name upstream as well?

@amol-
Copy link
Collaborator Author

amol- commented Jun 11, 2025

I thought we were calling this preview? or did we change the name upstream as well?

The name in Connect is "active", the word "preview" is primarily used as a verb to indicate the action of looking at a bundle that is not active, but not to set it as "active" or "not active".

during design there were a few discussions about glossary and one of the terms for the idea of deploying a new application with 0 active bundles was to deploy a draft. As a --not-active or --inactive option seemed terrible as a name, I chose to go for the "draft" name which seems to better convey the intent of the action, is short and is positive instead of negative (in the sense that "it does" instead of "it does not") which is usually better for command line options.

@edavidaja
Copy link
Collaborator

I think "preview deployment" is well-enough established as a noun in similar contexts (e.g. netlify, cloudflare, vercel, etc) that deploy --preview communicates the intent pretty clearly.

@amol-
Copy link
Collaborator Author

amol- commented Jun 11, 2025

I think "preview deployment" is well-enough established as a noun in similar contexts (e.g. netlify, cloudflare, vercel, etc) that deploy --preview communicates the intent pretty clearly.

Agreed that is common enough, but "preview" was moved to "activate" as a term in the API.
So if we really want to rename it I'd prefer to go for a name that at least has adherence to the same glossary used by the APIs. But I think in this context "draft" better conveys the concept in the context of content

Also vercel itself uses both terms to more or less convey a similar concept 😅
And in the context of Content (and content management systems which Connect has a lot in common with) the term "draft" is fairly more common (IE: Payload CMS Next.js CMS ).

Generally speaking, the term "draft" seems to be attached to a persistent state that is not public (a version of a content that I never published but will sit there forever)
While the term "preview" seems to be attached to a transient action (preview this, but once I close the preview it goes away)
That's why I'd be more fond of "draft" in this context.

@jonkeane
Copy link
Collaborator

Let's go with what's here in the code now (which IIRC, is draft) ultimately what we think it should be called and debating it here isn't helpful — what matters is what will land with our users. Let's keep this in mind when we do user testing and see if folks find ... --draft awkward and we can revisit then.

@amol- amol- merged commit 04be902 into main Jun 11, 2025
15 checks passed
@amol- amol- deleted the drafts-preview branch June 11, 2025 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants